package stone926.mods.more_enchantments.mixins;

import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.entity.mob.ZombieVillagerEntity;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import stone926.mods.more_enchantments.MoreEnchantmentsMod;
import stone926.mods.more_enchantments.interfaces.IEntitySpawnedByFlower;
import stone926.mods.more_enchantments.interfaces.IMobEntity;
import stone926.mods.more_enchantments.util.RandomUtil;

import java.util.UUID;

@Mixin(ZombieVillagerEntity.class)
public abstract class ZombieVillagerMixin extends Entity implements IEntitySpawnedByFlower {

  public ZombieVillagerMixin(EntityType<?> type, World world) {
    super(type, world);
  }

  @Shadow
  protected abstract void setConverting(@Nullable UUID uuid, int delay);

  @Redirect(method = "interactMob", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/mob/ZombieVillagerEntity;setConverting(Ljava/util/UUID;I)V"))
  private void setConverting(ZombieVillagerEntity zv, UUID uuid, int delay) {
    if (isSpawnedByMandala()) setConverting(uuid, 100);
    else setConverting(uuid, delay);
  }

  @Inject(method = "interactMob", at = @At("HEAD"), cancellable = true)
  private void redemption(PlayerEntity player, Hand hand, CallbackInfoReturnable<ActionResult> cir) {
    ItemStack stack = player.getStackInHand(hand);
    if (stack.isOf(MoreEnchantmentsMod.APPLE_OF_REDEMPTION_SINGLE) && !world.isClient) {
      setConverting(player.getUuid(), 4);
      stack.damage(RandomUtil.nextInt(1, 2, random), player, p -> p.sendToolBreakStatus(hand));
      cir.setReturnValue(ActionResult.CONSUME);
    }
  }

  @Redirect(method = "finishConversion", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/mob/ZombieVillagerEntity;convertTo(Lnet/minecraft/entity/EntityType;Z)Lnet/minecraft/entity/mob/MobEntity;"))
  private MobEntity convertTo(ZombieVillagerEntity zv, EntityType<VillagerEntity> targetType, boolean keepEquipment) {
    VillagerEntity villager;
    if (((IEntitySpawnedByFlower) zv).isSpawnedByMandala()) {
      villager = zv.convertTo(targetType, true);
      if (villager != null) {
        ((IEntitySpawnedByFlower) villager).setSpawnedByMandala(true);
        ((IMobEntity) villager).setAiDisableTicks(((IMobEntity) this).getAiDisableTicks());
      }
    } else villager = zv.convertTo(targetType, keepEquipment);
    return villager;
  }

}
